package com.itlong.cloud.controller.wechatofficial;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.itlong.cloud.POJO.DTO.app.APPServiceTemporaryCarBillDTO;
import com.itlong.cloud.POJO.DTO.app.AppMonthCarBillDTO;
import com.itlong.cloud.POJO.DTO.common.NettyServiceDTO;
import com.itlong.cloud.POJO.DTO.common.ParkingMessageDTO;
import com.itlong.cloud.POJO.DTO.common.ResultMessageDTO;
import com.itlong.cloud.POJO.PO.PropertyParkCouponPO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.app.AppGetCouponListVO;
import com.itlong.cloud.POJO.VO.app.AppMonthCardBillVO;
import com.itlong.cloud.POJO.VO.app.AppPayParkFeeNoticeVO;
import com.itlong.cloud.POJO.VO.app.AppServiceTemporaryCarBillVO;
import com.itlong.cloud.POJO.VO.miniprogram.WeChatOfficialGetMonthCardCarVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.annotation.UnAuthAccessRequired;
import com.itlong.cloud.annotation.UnParamEncrypt;
import com.itlong.cloud.common.network.tcp.netty.INettyServiceClient;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.enumerate.ParkingOrderTypeEnum;
import com.itlong.cloud.enumerate.PaySourceEnum;
import com.itlong.cloud.enumerate.ThirdPartPayTypeEnum;
import com.itlong.cloud.enumerate.ecode.AppErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.MiniProgramErrorCodeEnum;
import com.itlong.cloud.paymenthub.IAccountBalanceServiceClient;
import com.itlong.cloud.paymenthub.IWeChatPayServiceClient;
import com.itlong.cloud.project.app.IAppMonthCardParkingServiceClient;
import com.itlong.cloud.project.property.IParkCarHttpServiceClient;
import com.itlong.cloud.project.property.IPropertyAccountServiceClient;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.app.IAppCouponServiceClient;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 *      微信公众号停车场(云停车)相关功能控制器
 * </desc>
 *
 * @create 2019/04/01
 */
@RestController
@RequestMapping("/parking")
@RefreshScope
public class WeChatOfficialParkingController extends BaseController {

    private static final Logger LOG = LoggerFactory.getLogger(WeChatOfficialParkingController.class);

    //解密用
    @Value("${" + PlatformConstants.MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY + "}")
    public String MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY;

    @Value("${" + PlatformConstants.WECHAT_OFFICIAL_REQUEST_URL + "}")
    public String WECHAT_OFFICIAL_REQUEST_URL;

    @Value("${" + PlatformConstants.WECHAT_OFFICIAL_APPID + "}")
    public String WECHAT_OFFICIAL_APPID;

    @Value("${" + PlatformConstants.WECHAT_OFFICIAL_SECRET + "}")
    public String WECHAT_OFFICIAL_SECRET;

    @Autowired
    private IAppMonthCardParkingServiceClient iAppMonthCardParkingServiceClient;

    @Autowired
    IWeChatPayServiceClient wechatPayServiceClient;

    @Autowired
    private IAppCouponServiceClient iAppCouponServiceClient;

    @Autowired
    INettyServiceClient iNettyServiceClient;

    @Autowired
    IParkCarHttpServiceClient parkCarHttpServiceClient;

    @Autowired
    IAccountBalanceServiceClient iAccountBalanceServiceClient;

    @Autowired
    IPropertyAccountServiceClient iPropertyAccountServiceClient;

    @Autowired
    private RedisService redisService;

    /**
     * <desc>
     *      获取月卡车辆列表
     * </desc>
     *
     * @return MessageVO 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/04/01
     */
    @ResponseBody
    @UnAuthAccessRequired
    @PostMapping(path = "/getMonthCardCarList")
    public Object getMonthCardCarList(String plateNumber, String createTime, String sign) {
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            plateNumber=request.getAttribute("plateNumber")==null?null:request.getAttribute("plateNumber").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            //合法性验证
            if (StringUtils.isBlank(plateNumber)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("plateNumber", plateNumber);
            params.put("createTime", createTime);
            //验证签名
            if (!Md5EncryptUtil.checkAppSignValue(params, sign, MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }
            List<WeChatOfficialGetMonthCardCarVO> weChatOfficialGetMonthCardCarVOS = iAppMonthCardParkingServiceClient.getMonthCardCarList(plateNumber);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),weChatOfficialGetMonthCardCarVOS);
        } catch (Exception e) {
            throw new DataAccessException("【微信公众号_停车场】获取月卡车辆列表失败",e);
        }
    }

    /**
     *  <desc>
     *      获取微信openId
     *  </desc>
     *
     * @param code 微信参数
     * @return
     * @createDate 2019/04/01
     * @author Juguang.S
     */
    @RequestMapping(path = "/getOpenId",method = RequestMethod.POST)
    @ResponseBody
    @UnAuthAccessRequired
    @UnParamEncrypt
    public Object getOpenId(String code){
//        HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        code=request.getAttribute("code")==null?null:request.getAttribute("code").toString();
        Map<String, Object> map = new HashMap<>();
        String status = "1";
        String msg = "ok";
        String requestUrl = WECHAT_OFFICIAL_REQUEST_URL +"?appid="+WECHAT_OFFICIAL_APPID+"&secret="+WECHAT_OFFICIAL_SECRET+"&code="+code+"&grant_type=authorization_code";
        try {
            if(StringUtils.isBlank(code)){
                status = "0";//失败状态
                msg = "code为空";
            }else {
                System.out.println(requestUrl);
                // 发起GET请求获取凭证
                JSONObject jsonObject = HttpProtocolUtil.httpsRequest(requestUrl, "GET", null);
                if (jsonObject != null) {
                    try {
                        map.put("openid", jsonObject.getString("openid"));
                    } catch (JSONException e) {
                        // 获取token失败
                        status = "0";
                        msg = "code无效";
                    }
                }else {
                    status = "0";
                    msg = "code无效";
                }
            }
            map.put("status", status);
            map.put("msg", msg);
        } catch (Exception e) {
            throw new DataAccessException("【微信公众号_停车场】获取openId失败",e);
        }
        return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),map);
    }

    /**
     *  <desc>
     *      获取微信授权信息
     *  </desc>
     *
     * @return
     * @createDate 2019/04/03
     * @author Juguang.S
     */
//    @RequestMapping(path = "/getTicket",method = RequestMethod.POST)
//    @ResponseBody
//    @UnParamEncrypt
//    public Object getJsapiTicket(String url) throws Exception {
//        url = URLDecoder.decode(url, "UTF-8");
//        Map<String, String> map = new HashMap<>();
//        String requestUrl = "https://api.weixin.qq.com/cgi-bin/token"+"?appid="+WECHAT_OFFICIAL_APPID+"&secret="+WECHAT_OFFICIAL_SECRET+"&grant_type=client_credential";
//        try {
//            String ticket = "";
//            //先从缓存中取access_token和ticket其有效期为两个小时，如取不到再调接口获取
//            ticket = redisService.get(RedisConstant.WECHAT_OFFICIAL_TICKET);
//            //url = "http://develop.wx.jia-r.com/?code=0018eRlg2PT5xI0oGfmg2DZElg28eRlZ&state=";
//            if(StringUtils.isEmpty(ticket)){
//                //发起GET请求获取凭证
//                JSONObject jsonObject = HttpProtocolUtil.httpsRequest(requestUrl, "GET", null);
//                if (jsonObject != null) {
//                    String accessToken = jsonObject.getString("access_token");
//                    if(StringUtils.isNotEmpty(accessToken)){
//                        redisService.set(RedisConstant.WECHAT_OFFICIAL_ACCESS_TOKEN,RedisConstant.WECHAT_OFFICIAL_TIME,accessToken);
//                    }
//                    String requestSecondUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket"+"?access_token="+accessToken+"&type=JSAPI";
//                    JSONObject jsonObjectSecond = HttpProtocolUtil.httpsRequest(requestSecondUrl, "GET", null);
//                    if(jsonObjectSecond != null){
//                        ticket = jsonObjectSecond.getString("ticket");
//                        if(StringUtils.isNotEmpty(ticket)){
//                            redisService.set(RedisConstant.WECHAT_OFFICIAL_TICKET,RedisConstant.WECHAT_OFFICIAL_TIME,ticket);
//                        }
//                    }
//                }
//            }
//            map = Sha1EncryptUtil.getSign(ticket, url);
//        } catch (Exception e) {
//            throw new DataAccessException("【微信公众号_停车场】获取ticket失败",e);
//        }
//        return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),map);
//    }

    /**
     * <desc>
     *      生成月卡车辆缴费账单
     * </desc>
     *
     * @param appMonthCarBillDTO 生成账单所需参数
     * @return MessageVO 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2019/04/01
     */
    @ResponseBody
    @UnAuthAccessRequired
    @PostMapping(path = "/monCarBill")
    public Object getMonthCardCarList(AppMonthCarBillDTO appMonthCarBillDTO) {
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            appMonthCarBillDTO=HttpProtocolUtil.parseRequestParamToDTO(AppMonthCarBillDTO.class,request);
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("createTime", appMonthCarBillDTO.getCreateTime());
            params.put("carId", appMonthCarBillDTO.getCarId());
            params.put("projectId", appMonthCarBillDTO.getProjectId());
            params.put("month", appMonthCarBillDTO.getMonth());
            params.put("billId", appMonthCarBillDTO.getBillId());
            //验证签名
            if (!Md5EncryptUtil.checkAppSignValue(params, appMonthCarBillDTO.getSign(), MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }
            if (StringUtils.isEmpty(appMonthCarBillDTO.getCarId()) || StringUtils.isEmpty(appMonthCarBillDTO.getProjectId())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            AppMonthCardBillVO billVO = iAppMonthCardParkingServiceClient.monCarFeeBill(appMonthCarBillDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), billVO);
        } catch (Exception e) {
            throw new DataAccessException("【微信公众号_停车场】生成月卡车辆缴费账单失败", e);
        }
    }

    /**
     * <desc>
     *      获取用户优惠券列表
     * </desc>
     *
     * @return MessageVO 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/04/02
     */
    @ResponseBody
    @UnAuthAccessRequired
    @PostMapping(path = "/getCouponList")
    public Object getCouponList(String openId, String redeemCode, String projectId, String createTime, String sign) {
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            openId=request.getAttribute("openId")==null?null:request.getAttribute("openId").toString();
            redeemCode=request.getAttribute("redeemCode")==null?null:request.getAttribute("redeemCode").toString();
            projectId=request.getAttribute("projectId")==null?null:request.getAttribute("projectId").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            //合法性验证
            if (StringUtils.isBlank(openId)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("openId", openId);
            params.put("redeemCode", redeemCode);
            params.put("projectId", projectId);
            params.put("createTime", createTime);
            //验证签名
            if (!Md5EncryptUtil.checkAppSignValue(params, sign, MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }

            if (StringUtils.isNotBlank(redeemCode)) {
                // 验证该优惠券是否可用
                PropertyParkCouponPO propertyParkCouponPO = iAppCouponServiceClient.getCouponByRedeemCode(redeemCode);
                if (propertyParkCouponPO == null) {
                    return new MessageVO(MiniProgramErrorCodeEnum.COUPON_NOT_EXIST_ERR.getErrorCode());
                }
                if (propertyParkCouponPO.getRedeemStatus() == 2 && !redeemCode.equals(propertyParkCouponPO.getPhoneNum())) {
                    return new MessageVO(MiniProgramErrorCodeEnum.COUPON_REDEEM_STATUS_ERR.getErrorCode());
                }
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                Date endTime = simpleDateFormat.parse(simpleDateFormat.format(propertyParkCouponPO.getEndTime()));
                Date nowTime = simpleDateFormat.parse(simpleDateFormat.format(new Date()));
                if (endTime.compareTo(nowTime) < 0) {
                    return new MessageVO(MiniProgramErrorCodeEnum.COUPON_END_TIME_GONE_ERR.getErrorCode());
                }
                // 未兑换的优惠券进行一次兑换操作
                if (propertyParkCouponPO.getRedeemStatus() == 1) {
                    propertyParkCouponPO.setRedeemUser(openId);
                    propertyParkCouponPO.setPhoneNum(openId);
                    propertyParkCouponPO.setRedeemStatus(2);
                    propertyParkCouponPO.setUpdateTime(new Date());
                    iAppCouponServiceClient.addCoupons(propertyParkCouponPO);
                }
            }

            List<AppGetCouponListVO> couponList = iAppCouponServiceClient.getCouponList(openId, projectId, redeemCode, null);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), couponList);
        } catch (Exception e) {
            throw new DataAccessException("【微信公众号_停车场】获取用户优惠券列表失败",e);
        }
    }

    /**
     * <desc>
     *      调微信后台统一下单接口/商户后台保存订单
     * <desc/>
     *
     * @param total 支付金额
     * @param billsId 账单编号
     * @param feeType 缴费类型 1物业费 2维修费 3临时车缴费 4月卡缴费
     * @return 标准化响应结果
     * @author Juguang.S
     * @createDate 2019/04/02
     */
    @PostMapping(path = "/order")
    @ResponseBody
    @UnAuthAccessRequired
    public Object saveOrder(String total,String billsId, String openId, String createTime,String sign,String feeType) {

        //LOG.info("======saveOrder参数：total：" + total);
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            openId=request.getAttribute("openId")==null?null:request.getAttribute("openId").toString();
            total=request.getAttribute("total")==null?null:request.getAttribute("total").toString();
            billsId=request.getAttribute("billsId")==null?null:request.getAttribute("billsId").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            feeType=request.getAttribute("feeType")==null?null:request.getAttribute("feeType").toString();

            //验签
            Map<String, String> params = new HashMap<>();
            params.put("total", total);
            params.put("feeType", feeType);
            params.put("billsId", billsId);
            params.put("createTime", createTime);
            params.put("openId", openId);
            if (!Md5EncryptUtil.checkAppSignValue(params, sign, MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            } else if (StringUtils.isBlank(total) || StringUtils.isBlank(createTime) || StringUtils.isBlank(billsId) || StringUtils.isBlank(openId)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            } else if (Double.parseDouble(total) <= 0) {
                return new MessageVO(AppErrorCodeEnum.TRADE_AMCOUNT_ERR.getErrorCode());
            }
            //校验第三方支付管理微信支付是否被禁用
            if (wechatPayServiceClient.getThirdPayStatus(ThirdPartPayTypeEnum.WECHAT_PAY.getType()) == 0) {
                return new MessageVO(AppErrorCodeEnum.NOT_ALLOWED_WEICHAT_TRADE.getErrorCode());
            }
            //查询该账单是否已经被完成
            if (wechatPayServiceClient.getBillStatus(billsId) > 0) {
                return new MessageVO(AppErrorCodeEnum.BILL_PAY_SUCCESS.getErrorCode());
            }

            Map<Object, Object> resultMap = wechatPayServiceClient.saveOrder(total, openId, billsId, feeType, openId, PaySourceEnum.WECHAT_OFFICIAL_SOURCE.getType(),"",null,request.getRemoteAddr(),null,null);
//            if (resultMap.size() == 9 || resultMap.size() == 8) {
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), resultMap);
//            } else {
//                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), resultMap);
//            }

        } catch (Exception e) {
            throw new DataAccessException("【公众号_微信支付】API返回的数据异常", e);
        }
    }

    /**
     * <desc>
     *      添加(兑换)优惠券
     * </desc>
     *
     * @return MessageVO 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/04/02
     */
    @ResponseBody
    @UnAuthAccessRequired
    @PostMapping(path = "/addCoupon")
    public Object addCoupon(String openId, String redeemCode, String createTime, String sign) {
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            openId=request.getAttribute("openId")==null?null:request.getAttribute("openId").toString();
            redeemCode=request.getAttribute("redeemCode")==null?null:request.getAttribute("redeemCode").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            //合法性验证
            if (StringUtils.isBlank(openId) || StringUtils.isBlank(redeemCode)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("openId", openId);
            params.put("redeemCode", redeemCode);
            params.put("createTime", createTime);
            //验证签名
            if (!Md5EncryptUtil.checkAppSignValue(params, sign, MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }
            // 处理一下优惠券兑换码，可能是二维码扫出来的
            redeemCode = redeemCode.substring(redeemCode.indexOf("=") + 1, redeemCode.length());
            // 验证该优惠券是否可用
            PropertyParkCouponPO propertyParkCouponPO = iAppCouponServiceClient.getCouponByRedeemCode(redeemCode);
            if (propertyParkCouponPO == null) {
                return new MessageVO(MiniProgramErrorCodeEnum.COUPON_NOT_EXIST_ERR.getErrorCode());
            }
            if (propertyParkCouponPO.getRedeemStatus() == 2) {
                return new MessageVO(MiniProgramErrorCodeEnum.COUPON_REDEEM_STATUS_ERR.getErrorCode());
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date endTime = simpleDateFormat.parse(simpleDateFormat.format(propertyParkCouponPO.getEndTime()));
            Date nowTime = simpleDateFormat.parse(simpleDateFormat.format(new Date()));
            if (endTime.compareTo(nowTime) < 0) {
                return new MessageVO(MiniProgramErrorCodeEnum.COUPON_END_TIME_GONE_ERR.getErrorCode());
            }
            propertyParkCouponPO.setRedeemUser(openId);
            propertyParkCouponPO.setPhoneNum(openId);
            propertyParkCouponPO.setRedeemStatus(2);
            propertyParkCouponPO.setUpdateTime(new Date());
            AppGetCouponListVO couponVO = iAppCouponServiceClient.addCoupons(propertyParkCouponPO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), couponVO);
        } catch (Exception e) {
            throw new DataAccessException("【微信公众号_停车场】添加(兑换)优惠券失败", e);
        }
    }

     /**
     * <desc>
     *      处理零元支付
     * <desc/>
     *
     * @param
     * @return  标准化响应结果
     * @author Juguang.S
     * @createDate 2019/04/03
     */
    @ResponseBody
    @UnAuthAccessRequired
    @RequestMapping("/zeroPayment")
    public Object zeroPayment(String billsId, String createTime,String sign,String feeType) {
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            billsId=request.getAttribute("billsId")==null?null:request.getAttribute("billsId").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            feeType=request.getAttribute("feeType")==null?null:request.getAttribute("feeType").toString();
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("feeType",feeType);
            params.put("billsId",billsId);
            params.put("createTime",createTime);
            if (!Md5EncryptUtil.checkAppSignValue(params, sign,MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)){
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }else if (StringUtils.isBlank(billsId)||StringUtils.isBlank(feeType)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            //查询该账单是否已经被完成
            if (wechatPayServiceClient.getBillStatus(billsId) > 0) {
                return new MessageVO(AppErrorCodeEnum.BILL_PAY_SUCCESS.getErrorCode());
            }

            iAppMonthCardParkingServiceClient.noticeZeroPayment(billsId);
            AppPayParkFeeNoticeVO payParkFeeNoticeVO = wechatPayServiceClient.getZeroPaymentNotice(billsId);
            //处理临时停车缴费通知
            NettyServiceDTO nettyServiceDTO = parkCarHttpServiceClient.paymentParkFee(payParkFeeNoticeVO.getParkingCostsDTO());
            String projectId = payParkFeeNoticeVO.getParkingCostsDTO().getProjectId();
            try{
                iNettyServiceClient.synOrderByParking(nettyServiceDTO.getClientKey(),nettyServiceDTO.getContent(),nettyServiceDTO.getParkingBusinessOrderEnum(),nettyServiceDTO.getMessageId());
            }catch (Exception e){
                //返回失败则将requestContent放入队列进行处理
                wechatPayServiceClient.sendMessager(projectId,nettyServiceDTO.getContent(), ParkingOrderTypeEnum.PAYMENT_PARKING_FEE.getType());
            }

            Map<String,Object> map = new HashMap<>();
            map.put("paymentStatus","2");

            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),map);
        } catch (Exception e) {
            throw new DataAccessException("【微信公众号】处理零元支付失败", e);
        }
    }

    /**
     * <desc>
     *      检测订单状态是否为完成
     * <desc/>
     *
     * @param
     * @return  标准化响应结果
     * @author Juguang.S
     * @createDate 2019/04/04
     */
    @ResponseBody
    @UnAuthAccessRequired
    @RequestMapping("/checkTradeSuccess")
    public Object checkTradeSuccess(String createTime,String sign,String billsId,String tradeId) {
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            billsId=request.getAttribute("billsId")==null?null:request.getAttribute("billsId").toString();
            tradeId=request.getAttribute("tradeId")==null?null:request.getAttribute("tradeId").toString();
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("billsId",billsId);
            params.put("tradeId",tradeId);
            if (!Md5EncryptUtil.checkAppSignValue(params, sign,MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)){
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }else if (StringUtils.isBlank(billsId)||StringUtils.isBlank(tradeId)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            Map<String,Object> map = new HashMap<>();
            if(iAccountBalanceServiceClient.checkTradeSuccess(billsId,"",tradeId)){
                //根据账单ID查询月卡订单的截止时间
                String endTime = iAccountBalanceServiceClient.getMonthCardTime(billsId);
                if(StringUtils.isEmpty(endTime)){
                    map.put("remark","");
                }else{
                    map.put("remark",endTime);
                }
                //2代表订单支付成功  1代表支付未成功
                map.put("paymentStatus","2");
            }else {
                map.put("paymentStatus","1");
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),map);
        } catch (Exception e) {
            throw new DataAccessException("【微信公众号】检测订单状态是否为完成失败", e);
        }
    }


    /**
     * <desc>
     * 生成临时车辆停车账单
     * </desc>
     *
     * @param appServiceTemporaryCarBillDTO 生成账单必要信息
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2018/11/07
     */
    @PostMapping("temporaryCarBill")
    @ResponseBody
    @UnAuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.APP_CREATE_CAR_BILL)
    @UnParamEncrypt
    public Object temporaryCarBill(APPServiceTemporaryCarBillDTO appServiceTemporaryCarBillDTO) {
        try {
//            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//            appServiceTemporaryCarBillDTO=HttpProtocolUtil.parseRequestParamToDTO(APPServiceTemporaryCarBillDTO.class,request);
            if (StringUtils.isEmpty(appServiceTemporaryCarBillDTO.getPlateNumber())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            AppServiceTemporaryCarBillVO checkResult = iPropertyAccountServiceClient.checkCarBill(appServiceTemporaryCarBillDTO);
            //判断车辆是否进场
            if ("0".equals(checkResult.getIsParkingFlag())) {
                return new MessageVO(AppErrorCodeEnum.CAR_IS_NOT_PARKING_ERR.getErrorCode());
            }
            //判断车辆是否是月卡用户
            if ("0".equals(checkResult.getMoonCarFlag())) {
                return new MessageVO(AppErrorCodeEnum.MOON_CARD_IS_NOT_OVERDUE_ERR.getErrorCode());
            }
            //判断项目是否禁用
            if (!"1".equals(checkResult.getStatus())) {
                return new MessageVO(AppErrorCodeEnum.PAD_PROJECT_FORBIDDEN.getErrorCode());
            }

            //获取停车金额
            NettyServiceDTO nettyServiceDTO =
                    iPropertyAccountServiceClient.calculationAmount(
                            appServiceTemporaryCarBillDTO.getPlateNumber(), appServiceTemporaryCarBillDTO.getRedeemCode(), checkResult.getProjectId());
            iNettyServiceClient.synOrderByParking(
                    nettyServiceDTO.getClientKey(), nettyServiceDTO.getContent(), nettyServiceDTO.getParkingBusinessOrderEnum(), nettyServiceDTO.getMessageId());

            ParkingMessageDTO parkingMessageDTO;
            int count = 0;
            while (count < 10) {
                Thread.sleep(500);
                parkingMessageDTO = (ParkingMessageDTO)redisService.getObject(nettyServiceDTO.getMessageId(),ParkingMessageDTO.class);
                //LOG.info("【停车场查费messageId one】:"+nettyServiceDTO.getMessageId());
                if (parkingMessageDTO != null) {
                    ResultMessageDTO dto = JsonUtil.decode(parkingMessageDTO.getContent(), new TypeReference<ResultMessageDTO>() {});
                    if (!"0".equals(dto.getCode().toString())) {
                        return new MessageVO(AppErrorCodeEnum.GET_PARKING_ACCOUNT_ERR.getErrorCode());
                    }
                    appServiceTemporaryCarBillDTO.setAccount(new BigDecimal(dto.getMessage()));
                    LOG.info("account:" + dto.getMessage());
                    break;
                }
                count++;
            }
            ParkingMessageDTO parkingMessageDTO2;
            NettyServiceDTO nettyServiceDTO2 =
                    iPropertyAccountServiceClient.calculationAmount(
                            appServiceTemporaryCarBillDTO.getPlateNumber(), "", checkResult.getProjectId());
            iNettyServiceClient.synOrderByParking(
                    nettyServiceDTO2.getClientKey(), nettyServiceDTO2.getContent(), nettyServiceDTO2.getParkingBusinessOrderEnum(), nettyServiceDTO2.getMessageId());
            int count2 = 0;
            while (count2 < 10) {
                Thread.sleep(500);
                parkingMessageDTO2 = (ParkingMessageDTO)redisService.getObject(nettyServiceDTO2.getMessageId(),ParkingMessageDTO.class);
                LOG.info("【停车场查费messageId two】:"+nettyServiceDTO2.getMessageId());
                if (parkingMessageDTO2 != null) {
                    ResultMessageDTO dto2 = JsonUtil.decode(parkingMessageDTO2.getContent(), new TypeReference<ResultMessageDTO>() {});
                    appServiceTemporaryCarBillDTO.setAccountOld(new BigDecimal(dto2.getMessage()));
                    LOG.info("accountOld:" + dto2.getMessage());
                    break;
                }
                count2++;
            }
            if (appServiceTemporaryCarBillDTO.getAccount() == null || appServiceTemporaryCarBillDTO.getAccountOld() == null) {
                return new MessageVO(AppErrorCodeEnum.PARKING_BUSY_ERROR.getErrorCode());
            }
            AppServiceTemporaryCarBillVO result = iPropertyAccountServiceClient.temporaryCarBill(appServiceTemporaryCarBillDTO, "");
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), result);
        } catch (Exception e) {
            throw new DataAccessException("【小程序_服务】生成临时车辆停车账单失败", e);
        }
    }

}
